Skip to content

Integrate recent PickleScan bypasses into unsafe imports detection#210

Merged
thomas-chauchefoin-tob merged 7 commits intomasterfrom
integrate-picklescan-bypasses
Jan 22, 2026
Merged

Integrate recent PickleScan bypasses into unsafe imports detection#210
thomas-chauchefoin-tob merged 7 commits intomasterfrom
integrate-picklescan-bypasses

Conversation

@dguido
Copy link
Copy Markdown
Member

@dguido dguido commented Jan 22, 2026

Summary

Integrates 8+ CVEs and GHSAs discovered in PickleScan v0.0.31-v0.0.34 into fickling's unsafe imports detection, as requested in #190.

Bypasses now detected:

Changes:

File Changes
fickling/fickle.py Added ~35 modules to UNSAFE_IMPORTS frozenset
fickling/analysis.py Expanded UNSAFE_MODULES and UNSAFE_IMPORTS dicts with detailed descriptions
test/test_bypasses.py Added 7 new test cases for bypass detection

References:

Test plan

  • All 73 existing tests pass
  • All 7 new bypass test cases pass
  • Linting passes (ruff check)

🤖 Generated with Claude Code

Add detection for 8+ CVEs and GHSAs discovered in PickleScan v0.0.31-v0.0.34:

- Operator module bypasses (GHSA-m273-6v24-x4m4, GHSA-955r-x9j8-7rhh):
  _operator/operator.attrgetter, itemgetter, methodcaller
- File handling bypasses (CVE-2025-10155, CVE-2025-10156):
  distutils.file_util.write_file, _io.FileIO, shutil
- Async subprocess execution (CVE-2025-10157):
  asyncio.unix_events._UnixSubprocessTransport
- Profiler/debugger code execution (GHSA-46h3-79wf-xr6c, GHSA-4675-36f9-wf6r):
  profile, trace, pdb, bdb, timeit, doctest
- Nested pickle attacks (GHSA-84r2-jw7c-4r5q): pickle, _pickle
- Package manipulation (GHSA-vqmv-47xg-9wpr): pip, venv, ensurepip
- Network modules (GHSA-hgrh-qx5j-jfwx): aiohttp, httplib, http, ssl, requests
- IDE tools (GHSA-r8g5-cgf2-4m4m): idlelib, lib2to3
- numpy.f2py.crackfortran.getlincoef/_eval_length
- functools.partial wrapper bypass

Closes #190

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@dguido dguido requested a review from ESultanik as a code owner January 22, 2026 05:30
References were pointing to wrong advisories.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Keep only modules relevant to ML model scanning. General-purpose
modules remain in fickle.py UNSAFE_IMPORTS for standard detection.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace test_operator_methodcaller with actual exploit payload from
  GHSA-955r-x9j8-7rhh that chains __import__, _operator.methodcaller
  to call os.system()
- Replace test_asyncio_subprocess with payload from GHSA-f7qq-56ww-84cr
  targeting _UnixSubprocessTransport._start
- Add GHSA references to test_distutils_write_file and test_numpy_f2py_getlincoef
- Remove test_operator_attrgetter and test_functools_partial (redundant)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Pickle files may contain dotted attribute names like
`_UnixSubprocessTransport._start` in STACK_GLOBAL. Allow these
by validating each component separately.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Keep only ML-specific imports (torch, numpy) since other modules
  are already covered by fickle.py UNSAFE_IMPORTS at the module level
- Move _io/io from fickle.py to UnsafeImportsML with FileIO-only check
  to avoid false positives (io.BytesIO is commonly used legitimately)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@thomas-chauchefoin-tob
Copy link
Copy Markdown
Collaborator

Cleanup & Focus:

  • Removed incorrect CVE/GHSA references from comments
  • Reduced UnsafeImportsML to ML-relevant modules only
  • Removed duplicate entries where modules are already in the UnsafeImports analysis pass
  • Match only _io.FileIO / io.FileIO to avoid false positives

Test Improvements:

  • Use payloads from PickleScan advisories
  • Added proper GHSA references to tests

Bug Fix:

  • Fixed STACK_GLOBAL parser to accept dotted attribute names (e.g., _UnixSubprocessTransport._start)

@thomas-chauchefoin-tob thomas-chauchefoin-tob merged commit 19e828d into master Jan 22, 2026
11 checks passed
@thomas-chauchefoin-tob thomas-chauchefoin-tob deleted the integrate-picklescan-bypasses branch January 22, 2026 23:14
thomas-chauchefoin-tob added a commit that referenced this pull request Jan 23, 2026
This was erroneously added and later removed in PR #210. The visitor
override tracks visited nodes by id to prevent infinite recursion when
traversing cyclic AST structures created via MEMOIZE + GET opcodes.

Co-Authored-By: Dan Guido <dan@trailofbits.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>
thomas-chauchefoin-tob added a commit that referenced this pull request Jan 28, 2026
* Fix cyclic AST recursion DoS (issue #196)

Cyclic pickle structures (e.g., `L = []; L.append(L)`) caused
RecursionError when fickling analyzed them. This fix detects cycles
at mutation points (Append, Appends, SetItem, SetItems, AddItems)
and replaces self-references with `<cyclic-ref>` placeholder AST nodes.

Changes:
- Add `_has_cycle` flag to Interpreter to track cycle detection
- Modify mutation operations to check if value being added `is` the container
- Add `has_cycles` property to Pickled class for downstream awareness
- Update tests to verify the fix works correctly

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Restore cycle detection in ASTProperties visitor

This was erroneously added and later removed in PR #210. The visitor
override tracks visited nodes by id to prevent infinite recursion when
traversing cyclic AST structures created via MEMOIZE + GET opcodes.

Co-Authored-By: Dan Guido <dan@trailofbits.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>

* Merge and uniformize tests

* Add tests for all cycle detection corner cases

Cover dict value cycles, dict key cycles, and set cycles
to ensure the cycle detection feature handles all supported
mutation opcodes (SetItem, AddItems).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Fix AddItems to peek instead of pop the set

Match Python's pickle implementation which uses stack[-1] to peek
at the set without removing it from the stack.

Ref: https://github.com/python/cpython/blob/6ea3f8cd7ff4ff9769ae276dabc0753e09dca998/Lib/pickle.py#L1840

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Use Python-style repr for cyclic references

Match Python's repr output for cyclic structures:
- List cycles: [[...]] instead of [<cyclic-ref>]
- Dict cycles: {'key': {...}} instead of {'key': <cyclic-ref>}
- Set cycles: {{...}} instead of {<cyclic-ref>}

This makes fickling's AST output directly comparable to what Python
displays when printing cyclic data structures.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Raise InterpretationError for impossible cyclic structures

Match Python's behavior for unhashable cyclic references:
- Dict key cycles: raise InterpretationError (Python raises TypeError)
- Set cycles: raise InterpretationError (Python raises TypeError)
- Dict value cycles: still allowed with {...} placeholder
- List cycles: still allowed with [...] placeholder

This distinguishes between valid cyclic structures that Python can
represent (lists containing themselves, dicts with self-referencing
values) and impossible structures that would fail at runtime.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Thomas Chauchefoin <thomas.chauchefoin@trailofbits.com>
dguido added a commit that referenced this pull request Feb 20, 2026
Renames AGENTS.md to CLAUDE.md and expands it from vulnerability
reporting guidance into full project context: commands, architecture,
design rules, testing patterns, code style, and CI. Design rules
distilled from PR review history (#79, #87, #195, #207, #210, #220).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
thomas-chauchefoin-tob pushed a commit that referenced this pull request Feb 20, 2026
Renames AGENTS.md to CLAUDE.md and expands it from vulnerability
reporting guidance into full project context: commands, architecture,
design rules, testing patterns, code style, and CI. Design rules
distilled from PR review history (#79, #87, #195, #207, #210, #220).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants